package com.burst.reptile.framework.constant;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.burst.reptile.common.utils.DateUtil;
import com.burst.reptile.common.utils.NumberUtils;
import com.burst.reptile.common.utils.SecurityUtils;
import com.burst.reptile.common.utils.ToolUtil;
import com.burst.reptile.framework.config.SpringContextHolder;
import com.burst.reptile.modular.api.vo.BaseUser;
import com.burst.reptile.modular.api.vo.ReplyVo;
import com.burst.reptile.modular.system.entity.SysUser;
import com.burst.reptile.modular.system.mapper.SysUserMapper;
import com.burst.reptile.modular.zp.entity.ZpChatList;
import com.burst.reptile.modular.zp.entity.ZpCity;
import com.burst.reptile.modular.zp.entity.ZpCollect;
import com.burst.reptile.modular.zp.entity.ZpColumn;
import com.burst.reptile.modular.zp.entity.ZpCommSup;
import com.burst.reptile.modular.zp.entity.ZpComment;
import com.burst.reptile.modular.zp.entity.ZpFans;
import com.burst.reptile.modular.zp.entity.ZpFollow;
import com.burst.reptile.modular.zp.entity.ZpFormat;
import com.burst.reptile.modular.zp.entity.ZpNotice;
import com.burst.reptile.modular.zp.entity.ZpRec;
import com.burst.reptile.modular.zp.entity.ZpResources;
import com.burst.reptile.modular.zp.entity.ZpServiceItems;
import com.burst.reptile.modular.zp.entity.ZpVote;
import com.burst.reptile.modular.zp.mapper.ZpChatListMapper;
import com.burst.reptile.modular.zp.mapper.ZpCityMapper;
import com.burst.reptile.modular.zp.mapper.ZpCollectMapper;
import com.burst.reptile.modular.zp.mapper.ZpColumnMapper;
import com.burst.reptile.modular.zp.mapper.ZpCommSupMapper;
import com.burst.reptile.modular.zp.mapper.ZpCommentMapper;
import com.burst.reptile.modular.zp.mapper.ZpFansMapper;
import com.burst.reptile.modular.zp.mapper.ZpFollowMapper;
import com.burst.reptile.modular.zp.mapper.ZpFormatMapper;
import com.burst.reptile.modular.zp.mapper.ZpNoticeMapper;
import com.burst.reptile.modular.zp.mapper.ZpRecMapper;
import com.burst.reptile.modular.zp.mapper.ZpResourcesMapper;
import com.burst.reptile.modular.zp.mapper.ZpServiceItemsMapper;
import com.burst.reptile.modular.zp.mapper.ZpVoteMapper;

import cn.hutool.core.bean.BeanUtil;

/**
 * 快捷查询方法
 * @author wujin
 *
 * @date: 2020年6月19日 上午9:58:31
 */
@Component
@DependsOn("springContextHolder")
public class ConstantFactory implements IConstantFactory{

    private SysUserMapper userMapper = SpringContextHolder.getBean(SysUserMapper.class);
    
    private ZpFansMapper fansMapper = SpringContextHolder.getBean(ZpFansMapper.class);
    
    private ZpFollowMapper followMapper = SpringContextHolder.getBean(ZpFollowMapper.class);
    
    private ZpVoteMapper voteMapper = SpringContextHolder.getBean(ZpVoteMapper.class);
    
    private ZpCollectMapper collectMapper = SpringContextHolder.getBean(ZpCollectMapper.class);
    
    private ZpResourcesMapper resourcesMapper = SpringContextHolder.getBean(ZpResourcesMapper.class);
    
    private ZpServiceItemsMapper serviceItemsMapper = SpringContextHolder.getBean(ZpServiceItemsMapper.class);
    
    private ZpCityMapper cityMapper = SpringContextHolder.getBean(ZpCityMapper.class);
    
    private ZpCommentMapper commentMapper = SpringContextHolder.getBean(ZpCommentMapper.class);
    
    private ZpCommSupMapper commSupMapper = SpringContextHolder.getBean(ZpCommSupMapper.class);
    
    private ZpFormatMapper formatMapper = SpringContextHolder.getBean(ZpFormatMapper.class);
    
    private ZpRecMapper recMapper = SpringContextHolder.getBean(ZpRecMapper.class);
    
    private ZpColumnMapper columnMapper = SpringContextHolder.getBean(ZpColumnMapper.class);
    
    private ZpNoticeMapper noticeMapper = SpringContextHolder.getBean(ZpNoticeMapper.class);
    
    private ZpChatListMapper chatListMapper = SpringContextHolder.getBean(ZpChatListMapper.class);
    
    public static IConstantFactory me() {
        return SpringContextHolder.getBean("constantFactory");
    }

	@Override
	public SysUser getUser(Long userId) {
		return userMapper.selectById(userId);
	}

	@Override
	public String getFans(Long userId) {
		Integer selectCount = fansMapper.selectCount(new QueryWrapper<ZpFans>().eq("user_id", userId));
		return NumberUtils.amountConversion(selectCount);
	}

	@Override
	public String getAttention(Long userId) {
		Integer selectCount = followMapper.selectCount(new QueryWrapper<ZpFollow>().eq("user_id", userId));
		return NumberUtils.amountConversion(selectCount);
	}

	@Override
	public String getLikes(Long userId) {
		Integer selectCount = voteMapper.selectCount(new QueryWrapper<ZpVote>().eq("user_id", userId));
		return NumberUtils.amountConversion(selectCount);
	}

	@Override
	public String getReleaseVolume(Long userId) {
		Integer selectCount = resourcesMapper.selectCount(new QueryWrapper<ZpResources>().eq("user_id", userId).eq("draft", "0"));
		return NumberUtils.amountConversion(selectCount);
	}

	@Override
	public boolean mutual(Long userId, Long loginUserId) {
		Integer selectCount = followMapper.selectCount(new QueryWrapper<ZpFollow>().eq("user_id", loginUserId).eq("user_to_follow_id", userId));
		return selectCount > 0;
	}

	@Override
	public ZpResources getResources(Long articleId) {
		return resourcesMapper.selectById(articleId);
	}

	@Override
	public String getCollects(Long userId) {
		Integer selectCount = collectMapper.selectCount(new QueryWrapper<ZpCollect>().eq("user_id", userId));
		return NumberUtils.amountConversion(selectCount);
	}

	@Override
	public String getserviceItemsName(Integer serviceItems) {
		ZpServiceItems selectById = serviceItemsMapper.selectById(serviceItems);
		if(ToolUtil.isNotEmpty(selectById)) {
			return selectById.getName();
		}
		return "";
	}

	@Override
	public String getAddressName(String county) {
		ZpCity selectById = cityMapper.selectById(county);
		if(ToolUtil.isNotEmpty(selectById)) {
			return selectById.getShortName();
		}
		return "";
	}

	@Override
	public List<ReplyVo> replyList(Long cid) {
		List<ReplyVo> list = new ArrayList<>();
		List<ZpComment> selectList = commentMapper.selectList(new QueryWrapper<ZpComment>().eq("acid", cid).eq("ctype", "1").orderByDesc("create_time"));
		if(ToolUtil.isNotEmpty(selectList)) {
			list = selectList.stream().map(i -> {
				Long userId = i.getUserId();
				Long touserId = i.getTouserId();
				ReplyVo reply = new ReplyVo();
				reply.setCid(i.getCid());
				reply.setContent(i.getContent());
				reply.setCreateTime(i.getCreateTime());
				reply.setLikes(i.getLikes());
				SysUser user = this.getUser(userId);
				BaseUser roperties = new BaseUser();
				BeanUtil.copyProperties(user, roperties);
				reply.setRespondents(roperties);
				SysUser u = this.getUser(touserId);
				BaseUser touserUser = new BaseUser();
				BeanUtil.copyProperties(u, touserUser);
				reply.setUser(touserUser);
				reply.setUserId(i.getUserId());
				if(SecurityUtils.isLogin()) {
					Long loginUserId = SecurityUtils.getLoginUserId();
					reply.setOwn(userId.equals(loginUserId));
					reply.setSupport(this.isSupport(loginUserId, i.getCid()));
				}
				reply.setTime(DateUtil.timeToFormat(i.getCreateTime()));
				reply.setLikes(this.getCommentLikes(i.getCid()));
				return reply;
			}).collect(Collectors.toList());
		}
		return list;
	}

	@Override
	public String getCommentNum(Long articleId) {
		Integer selectCount = commentMapper.selectCount(new QueryWrapper<ZpComment>().eq("article_id", articleId));
		return NumberUtils.amountConversion(selectCount);
	}

	@Override
	public boolean isSupport(Long loginUserId, Long cid) {
		return commSupMapper.selectCount(new QueryWrapper<ZpCommSup>().eq("user_id", loginUserId).eq("cid", cid)) > 0;
	}

	@Override
	public Integer getCommentLikes(Long cid) {
		Integer selectCount = commSupMapper.selectCount(new QueryWrapper<ZpCommSup>().eq("cid", cid));
		return ToolUtil.isEmpty(selectCount) ? 0 : selectCount;
	}

	@Override
	public String getFormatName(Integer formatId) {
		if(ToolUtil.isNotEmpty(formatId)) {
			ZpFormat selectById = formatMapper.selectById(formatId);
			if(ToolUtil.isNotEmpty(selectById)) {
				return selectById.getFormatName();
			}
		}
		return null;
	}

	@Override
	public int getRec(Long articleId) {
		Integer selectCount = recMapper.selectCount(new QueryWrapper<ZpRec>().eq("article_id", articleId));
		return ToolUtil.isNotEmpty(selectCount) && selectCount > 0 ? 1 : 0;
	}

	@Override
	public String getColumnName(Integer columnId) {
		ZpColumn selectById = columnMapper.selectById(columnId);
		if(ToolUtil.isNotEmpty(selectById)) {
			return selectById.getColumnName();
		}
		return null;
	}

	@Override
	public Integer replyNum(Long cid) {
		return commentMapper.selectCount(new QueryWrapper<ZpComment>().eq("acid", cid).eq("ctype", "1"));
	}

	@Override
	public String getBePraised(Long userId) {
		Integer selectCount = voteMapper.selectCount(new QueryWrapper<ZpVote>().eq("author_id", userId));
		return NumberUtils.amountConversion(selectCount);
	}

	@Override
	public Integer getDraftsNum(Long userId) {
		return resourcesMapper.selectCount(new QueryWrapper<ZpResources>().eq("user_id", userId).eq("draft", "1"));
	}

	@Override
	public Integer getMsgNum(Long userId) {
		QueryWrapper<ZpNotice> queryWrapper = new QueryWrapper<>();
			queryWrapper.in("notice_type", Arrays.asList("1", "3", "4", "6"));
			queryWrapper.and(i -> i.eq("relation_user", userId).or().isNull("relation_user"));
			queryWrapper.eq("sign", "0");
			queryWrapper.eq("notice_status", "0");
		Integer selectCount = noticeMapper.selectCount(queryWrapper);
		return selectCount;
	}

	@Override
	public Integer getPrivateLetterNum(Long userId) {
		if(ToolUtil.isEmpty(userId)) {
			return 0;
		}
		QueryWrapper<ZpChatList> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("user_id", userId);
		queryWrapper.gt("unread", 0);
		List<ZpChatList> selectList = chatListMapper.selectList(queryWrapper);
		int sum = selectList.stream().mapToInt(ZpChatList::getUnread).sum();
		return sum;
	}
    
}
